#include "Connections.h"
#include <exception/NpException.h>
#include <string.h>
#include <string>
#include <config/Config.h>

using namespace npexception;
using namespace std;
using namespace dbinfo;

Connections::Connections()
{
  closeConn();
}

Connections::~Connections()
{
  closeConn();
}

Connections* Connections::getInstance()
{
  static Connections* singleton = new Connections();
  return singleton;
}

void Connections::addConnection(const string& key, const dbinfo::DBInfo &dbinfo)
{
  MYSQL* tmp = mysql_init((MYSQL*)0);
  bool flag = (tmp != NULL && mysql_real_connect(tmp,
                                                 dbinfo.dbip.c_str(),
                                                 dbinfo.dbuser.c_str(),
                                                 dbinfo.dbpasswd.c_str(),
                                                 dbinfo.dbname.c_str(),
                                                 dbinfo.port,
                                                 NULL,
                                                 0) != NULL);
  throwExIf(flag == false, ADD_MYSQL_ERROR);
  static const char* query = "set NAMES 'utf8'";
  throwExAndDoIf((mysql_real_query(tmp, query, strlen(query)) != 0), ADD_MYSQL_ERROR,
                 traceBug(BUG);
      NpLogger::getInstance()->infoLog(mysql_error(tmp)));
  throwExAndDoIf((mysql_select_db(tmp, dbinfo.dbname.c_str()) != 0), ADD_MYSQL_ERROR,
                 traceBug(BUG);
      NpLogger::getInstance()->infoLog(mysql_error(tmp)));
  m_conns[key] = tmp;
}

MYSQL* Connections::getConnection(const std::string &key)
{
  static ConnMapIterator it;
  it = m_conns.find(key);
  throwExIf(it == m_conns.end(), INVALID_CONN_KEY);
  return it->second;
}

void Connections::closeConn()
{
  for (ConnMapIterator it = m_conns.begin(); it != m_conns.end(); ++it)
  {
    static MYSQL* tmp;
    tmp = it->second;
    if (tmp != NULL)
    {
      mysql_close(tmp);
      it->second = NULL;
    }
  }
  m_conns.clear();
}

void Connections::init()
{
  closeConn();
  static DBInfo dbinfo;

  //主站
  string connStr = Config::getInstance()->getConfig()->connstring;
  if (connStr !="")
  {
    getDbInfo(connStr, dbinfo);
    addConnection(Config::getInstance()->getConfig()->flag + "source", dbinfo);
  }

  getDbInfo(Config::getInstance()->getConfig()->targetconnstring, dbinfo);
  addConnection(Config::getInstance()->getConfig()->flag + "target", dbinfo);

  //其它网站
  for (int i = 1; i < Config::getInstance()->getSize(); ++i)
  {
    getDbInfo(Config::getInstance()->getConfig(1)->targetconnstring, dbinfo);
    addConnection(Config::getInstance()->getConfig(1)->flag + "target", dbinfo);
  }
}

void Connections::getDbInfo(const string& connString, dbinfo::DBInfo &dbInfo)
{
  string str("Data Source=");
  int begin =connString.find(str, 0);
  int end = connString.find(";", begin);
  dbInfo.dbip = connString.substr(begin+str.length(), end-begin-str.length());

  str = "Database=";
  begin = connString.find(str, end);
  end = connString.find(";", begin);
  dbInfo.dbname = connString.substr(begin + str.length(), end-begin-str.length());

  str = "User ID=";
  begin = connString.find(str, end);
  end = connString.find(";", begin);
  dbInfo.dbuser = connString.substr(begin + str.length(), end-begin-str.length());

  str = "Password=";
  begin = connString.find(str,end);
  end = connString.find(";",begin);
  dbInfo.dbpasswd = connString.substr(begin + str.length(), end-begin-str.length());

  str = "port=";
  begin = connString.find(str, end);
  end = connString.find(";", begin);
  dbInfo.port = atoi(connString.substr(begin + str.length(),end - begin - str.length()).c_str());
  //Data Source=127.0.0.1;Database=数据库名;User ID=用户名;Password=密码;port=3306;charset=gbk
}
